﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BoYuanCore.DBServices.Base;
using BoYuanCore.Framework.MemoryCache;

namespace BoYuanCore.DBServices
{
    public class SysModule
    {
        private const string cacheKey = nameof(Entities.SysModule);
        /// <summary>
        /// 获取id(没有并发，所以以maxid获取最新的id)
        /// </summary>
        /// <returns></returns>
        public static int GetID()
        {
            int maxId=FreeSqlHelper.Fsql.Select<Entities.SysModule>().OrderByDescending(p=>p.ID).First(p=>p.ID);
            return maxId + 1;
        }

        /// <summary>
        /// 更新字体图标
        /// </summary>
        /// <param name="fontIcon">字体图标</param>
        /// <param name="id"></param>
        /// <returns></returns>
        public static bool UpdateFontIcon(string fontIcon, int id)
        {
            Entities.SysModule mo = new Entities.SysModule();
            mo.FontIcon = fontIcon == "None" ? string.Empty : fontIcon;
            mo.Icon = string.Empty;
            mo.ID = id;

            return FreeSqlHelper.Fsql.Update<Entities.SysModule>().
                SetSource(mo).UpdateColumns(p => new { p.FontIcon, p.Icon }).ExecuteAffrows() > 0;
        }

        /// <summary>
        /// 更新页面组件(包括父节点和子节点相关信息),并更新缓存
        /// </summary>
        /// <param name="mo"></param>
        /// <returns></returns>
        public static bool UpdateModuleByEntity(Entities.SysModule mo, ICachingProvider _iCachingProvider)
        {
            //验证
            if (mo.ID == mo.ParentID)
            {
                return false;
            }

            var db = FreeSqlHelper.Fsql;
            bool result;
            mo.TreePath = mo.TreePath + mo.ID + ",";

            Entities.SysModule moOld = FreeSqlHelper.GetModel<Entities.SysModule>(mo.ID);

            if (moOld.ParentID == mo.ParentID)//如果节点不变，直接更新即可
            {
                //更新实体
                result = db.Update<Entities.SysModule>().SetSource(mo).UpdateColumns(
                    p => new { p.IsHidden, p.PageTitle, p.Remark, p.Sort,  p.Url,p.ButtonText,p.ButtonID }
                ).ExecuteAffrows()>0;

                //更新缓存
                DBServices.SysModule.RemoveSysModuleListCache(_iCachingProvider);
                return result;
            }


            //判断父节点是否为根节点,更新父节点为非叶
            if (mo.ParentID != 0) db.Update<Entities.SysModule>().Set(p => new Entities.SysModule() { IsLeaf = false }).Where( p => p.ID == mo.ParentID).ExecuteAffrows();


            //获取原来的子节点集合
            List<Entities.SysModule> sysModuleList = db.Select<Entities.SysModule>().Where(p => p.TreePath.StartsWith(moOld.TreePath)).ToList();

            foreach (var sysModule in sysModuleList)//更新TreePath
            {
                sysModule.TreePath = mo.TreePath + sysModule.TreePath.Substring(moOld.TreePath.Length);
            }

            //更新子集合 (数据库截取字符串效果很差，各个版本数据库都不一致，故查询出来进行批量更新)
            int tempInt = db.Update<Entities.SysModule>()
                .SetSource(sysModuleList)
                .UpdateColumns(p => new { p.TreePath })
                .ExecuteAffrows();

            //更新当前实体
            result = db.Update<Entities.SysModule>().SetSource(mo).UpdateColumns(
                                  p => new { p.IsHidden, p.PageTitle, p.ParentID, p.Remark, p.Sort, p.TreePath, p.Url, p.ButtonText, p.ButtonID }
                              ).ExecuteAffrows() > 0;

            //更新缓存
            DBServices.SysModule.RemoveSysModuleListCache(_iCachingProvider);
            return result;
        }


        /// <summary>
        /// 更新绝对路径
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static bool UpdateTreePath(int id)
        {
            var db = FreeSqlHelper.Fsql;

            string strId = id.ToString();

            var mo = FreeSqlHelper.GetModel<Entities.SysModule>(id);
            var parenMo = FreeSqlHelper.GetModel<Entities.SysModule>(mo.ParentID);

            if (parenMo==null)
            {
                return db.Update<Entities.SysModule>(id)
                    .Set(p => p.TreePath == strId+ ",")
                    .ExecuteAffrows() > 0;
            }
            else
            {
                return db.Update<Entities.SysModule>(id)
                           .Set(p => p.TreePath == parenMo.TreePath+ strId + ",")
                           .ExecuteAffrows() > 0;
            }

            /* freesql 不支持set 子查询
            string sql = db.Update<Entities.SysModule>(id)
                .Set(p => p.TreePath == db.Select<Entities.SysModule>().Where(m => m.ID == p.ParentID)
                    .First(m => m.TreePath + strId + ","))
                .ToSql();
            */
        }

        /// <summary>
        /// 更新节点为叶子。
        /// </summary>
        public static void UpdateTreeLeaf()
        {
            var db = FreeSqlHelper.Fsql;
             
            //更新父节点不是叶
            int tempNum = db.Select<Entities.SysModule>()
                .Where(p => db.Select<Entities.SysModule>().Where(m => p.ID == m.ParentID ).Any() && string.IsNullOrEmpty(p.ButtonID))
                .ToUpdate()
                .Set(p => new Entities.SysModule() { IsLeaf = false })
                .ExecuteAffrows();

            //更新是非父节点是叶
            tempNum = db.Select<Entities.SysModule>()
                .Where(p => !db.Select<Entities.SysModule>().Where(m => p.ID == m.ParentID ).Any() && string.IsNullOrEmpty(p.ButtonID))
                .ToUpdate()
                .Set(p => new Entities.SysModule() { IsLeaf = true })
                .ExecuteAffrows();
        }


        /// <summary>
        /// 得到一个对象实体(父级的绝对路径)
        /// </summary>
        public static Entities.SysModule GetTreePathModel(int id)
        {
            var db =  FreeSqlHelper.Fsql;
            //获取父级的绝对路径

            return db.Select<Entities.SysModule>()
                .Where(p => p.ID == id)
                .First(p => new Entities.SysModule
                {
                    ID = p.ID,
                    FontIcon = p.FontIcon,
                    Icon = p.Icon,
                    IsHidden = p.IsHidden,
                    IsLeaf = p.IsLeaf,
                    PageTitle = p.PageTitle,
                    ParentID = p.ParentID,
                    Remark = p.Remark,
                    Sort = p.Sort,
                    TreePath = db.Select<Entities.SysModule>().Where(m => m.ID == p.ParentID).First(m=>m.TreePath),
                    Url = p.Url
                });

        }

        /// <summary>
        /// 获取所有页面组件数据，在缓存中。
        /// </summary>
        /// <param name="_iCachingProvider"></param>
        /// <param name="haveButtonPermissions">是否含有button权限</param>
        /// <returns></returns>
        public static List<Entities.SysModule> GetSysModuleListByCache(ICachingProvider _iCachingProvider, bool haveButtonPermissions=false)
        {
            return  _iCachingProvider.GetOrSetObjectFromCache(cacheKey+"@All", () =>
            {
                var db = FreeSqlHelper.Fsql;
                return db.Select<Entities.SysModule>()
                    .WhereIf(!haveButtonPermissions, p => string.IsNullOrEmpty(p.ButtonID))
                    .ToList();
            },4*60);//获取所有组件,4个小时
        }

        /// <summary>
        /// 更新组件list缓存
        /// </summary>
        /// <param name="_iCachingProvider"></param>
        public static void RemoveSysModuleListCache(ICachingProvider _iCachingProvider)
        {
            _iCachingProvider.Remove(cacheKey + "@All");//更新缓存
        }


        /*
        /// <summary>
        /// 页面角色id 获取页面组件数据
        /// </summary>
        /// <param name="sysRolepopedom_id">页面权限id</param>
        /// <returns></returns>
        public static DataSet GetListBySysRolepopedomId(int sysRolepopedom_id)
        {
            var db =  FreeSqlHelper.Fsql;
            string sql = @"SELECT    sm.*
                                            FROM   SysModule AS sm
                                            WHERE  (
                                                       SELECT ',' + moduleid + ','
                                                       FROM   SysRolepopedom AS sr
                                                       WHERE  sr.id = @id
                                                   ) LIKE '%,' + CAST(sm.id AS VARCHAR(20)) + ',%' ";

            return db.Ado.GetDataSetAll(sql, new { id = sysRolepopedom_id });
        }

        /// <summary>
        /// 判断页面权限
        /// </summary>
        /// <param name="rid">权限角色id</param>
        /// <param name="url">当前页面url</param>
        /// <returns></returns>
        public static bool IsRole(int rid, string url)
        {
            #region 老代码
            //var db =  FreeSqlHelper.Fsql;
            //string sql = @"SELECT COUNT(1)
            //                FROM   SysModule AS sm
            //                WHERE  (
            //                           SELECT ',' + moduleid + ','
            //                           FROM   SysRolepopedom AS sr
            //                           WHERE  sr.id = @id AND sr.isdel=0
            //                       ) LIKE '%,' + CAST(sm.id AS VARCHAR(20)) + ',%' and moduleUrl=@moduleUrl  ";

            //object obj= db.Ado.GetScalar(sql, new {id = rid, moduleUrl = url}) ;

            //if (obj == null)
            //{
            //    return false;
            //}
            //else
            //{
            //    return Convert.ToInt32(obj) > 0;
            //}
            #endregion

            var db =  FreeSqlHelper.Fsql;
            //从缓存中读取
            var role = db.GetModel_WithCache<Entities.SysRolepopedom>(rid);
            if (role.isdel > 0) return false;

            string tempStr = "," + role.moduleid + ",";
            bool haveRole = db.Queryable<Entities.SysModule>()
                .Where(p => tempStr.Contains("," + p.id.ToString() + ",") && p.moduleUrl == url)
                .WithCache()
                .Any();

            return haveRole;

        }
        */
    }
}
